#include "stdafx.h"
#include "Bin.h"
#include "File.h"
#include "HttpFx.h"
#include "Registry.h"
#include "UsbHid.h"
#include "UpgraDev.h"

UpgraDev::UpgraDev(void){
	bin=0;
	sum=0;
	ver=0;
	memset(&report,0,sizeof(report));
	report.cmd=RPT_FIRMWARE;
}
UpgraDev::~UpgraDev(void){
	if(bin)
		delete bin;
}

void UpgraDev::loadBin(TCHAR* sn,ushort version){
	if(sum)
		return;
	String* n=0;
	Bin*	b=0;
	try{
		MachineOrUser reg(version&1?L"Software\\Phoxell\\Kalkr\\firmware.0":
			L"Software\\Phoxell\\Kalkr\\firmware.1");
		ver=(ushort)reg.get(L"version",0);
		if(ver<=version)
			throw(0);
		n=reg.get(0,(PTSTR)0);
		File f(n);
		b=f.get();
		uint m=b->checkSum();
		if(m==reg.get(L"checksum",0)){
			bin=b;
			sum=m;
			delete n;
			return;
		}
	}catch(int){
	}
	if(b){
		delete b;
		b=0;
	}
	HttpFx* h=0;
	try{
		h=new HttpFx(sn,version);
		b=h->get(L"/kalkr/firmware",sn,version);
		ver=(ushort)h->version;
		if(ver>version){
			bin=b;
			sum=h->checksum;
			delete h;
			return;
		}
	}catch(int){
	}
	if(h)
		delete h;
	if(b)
		delete b;
	if(n)
		delete n;
	sum=1;
}
Report* UpgraDev::upgrade(Report *input){
	if(bin){
		ushort ofs=ver&1?0x8800:0x800;
		if(input){
			if(input->ord==0xffff)
				return 0;
			report.ord=memcmp(&input->cmd,&report.cmd,64)?ofs:input->ord+60;
		}else if(report.ord && (UsbHid::localTick()-timer<10))
			return 0;
		else report.ord=ofs;
		report.cmd=RPT_FIRMWARE;
		if(((uint)report.ord-ofs)>bin->getLength()){
			report.ord=0xffff;
			uint m=bin->checkSum();
			report.data[0]=m&0xffff;
			report.data[1]=m>>16;
			memset(&report.data[2],0,56);
		}else bin->copy(report.data,report.ord-ofs,60);
		timer=UsbHid::localTick();
		return &report;
	}else return 0;
}